/*
由于没有使用字典主动链接vector<T>，所以需要使用vector<T>*point来读取vector<T>>

*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <ctime>
#include <yaml-cpp/yaml.h>

using namespace std;

#include "TFile.h"
#include "TTree.h"
#include "setup.h"  // 确保包含 UseCoarse, TimeCrs_ToF, TimeSft_ToF, finalFileName

void RawRoot2Sort_ToF()
{
    for (auto &sRun_ToF : finalFileName)
    {
        clock_t start = clock();
        string sRawRoot = "../RootData/ToF_" + sRun_ToF + ".root";
        string sSort = "../RootData/ToF_Sort_" + sRun_ToF + ".root";

        printf("\n**********Now converting %s to %s!**********\n\n", sRawRoot.c_str(), sSort.c_str());

        TFile *fRaw = new TFile(sRawRoot.c_str());
        if (fRaw->IsZombie())
        {
            cerr << "Error: Cannot open " << sRawRoot << endl;
            delete fRaw;
            continue;
        }

        TTree *treeRaw_ToF = nullptr;
        fRaw->GetObject("treeRaw_ToF", treeRaw_ToF);
        if (!treeRaw_ToF)
        {
            cerr << "Error: Tree 'treeRaw_ToF' not found in " << sRawRoot << endl;
            fRaw->Close();
            delete fRaw;
            continue;
        }

        // --- 指针方式声明变量（关键！）---
        long long tsSlcRaw_ToF = 0;
        int nSigRaw_ToF = 0;

        vector<long long> *coarseRaw_ToF = nullptr;
        vector<short> *iBdRaw_ToF = nullptr;
        vector<short> *chRaw_ToF = nullptr;
        vector<short> *shiftRaw_ToF = nullptr;
        vector<short> *fineRaw_ToF = nullptr;

        // --- 绑定分支 ---
        treeRaw_ToF->SetBranchAddress("tsSlc_ToF", &tsSlcRaw_ToF);
        treeRaw_ToF->SetBranchAddress("nSig_ToF", &nSigRaw_ToF);
        treeRaw_ToF->SetBranchAddress("coarse_ToF", &coarseRaw_ToF);
        treeRaw_ToF->SetBranchAddress("fine_ToF", &fineRaw_ToF);
        treeRaw_ToF->SetBranchAddress("shift_ToF", &shiftRaw_ToF);
        treeRaw_ToF->SetBranchAddress("ch_ToF", &chRaw_ToF);
        treeRaw_ToF->SetBranchAddress("iBd_ToF", &iBdRaw_ToF);

        Long64_t nEnt = treeRaw_ToF->GetEntries();
        vector<pair<long long, Long64_t>> pair_SlcEnt;
        pair_SlcEnt.reserve(nEnt);

        for (Long64_t iEnt = 0; iEnt < nEnt; ++iEnt)
        {
            treeRaw_ToF->GetEntry(iEnt);
            pair_SlcEnt.emplace_back(tsSlcRaw_ToF, iEnt);
        }
        sort(pair_SlcEnt.begin(), pair_SlcEnt.end());

        // --- 输出文件 ---
        TFile *fSort = new TFile(sSort.c_str(), "RECREATE");
        TTree *treeSort_ToF = new TTree("treeSort_ToF", "Sorted ToF data");

        long long tsSlcSort_ToF = 0;
        int nSig_ToF = 0;
        vector<double> tmStpSort_ToF, coarseSort_ToF, shiftSort_ToF;
        vector<short> fineSort_ToF, brdSort_ToF, chSort_ToF;

        treeSort_ToF->Branch("sRun_ToF", &sRun_ToF);
        treeSort_ToF->Branch("tsSlcSort_ToF", &tsSlcSort_ToF, "tsSlcSort_ToF/L");
        treeSort_ToF->Branch("nSig_ToF", &nSig_ToF, "nSig_ToF/I");
        treeSort_ToF->Branch("brd_ToF", &brdSort_ToF);
        treeSort_ToF->Branch("ch_ToF", &chSort_ToF);
        treeSort_ToF->Branch("tmStpSort_ToF", &tmStpSort_ToF);
        treeSort_ToF->Branch("shift_ToF", &shiftSort_ToF);
        treeSort_ToF->Branch("coarse_ToF", &coarseSort_ToF);
        treeSort_ToF->Branch("fine_ToF", &fineSort_ToF);

        // --- 按时间片处理 ---
        Long64_t iEnt = 0;
        int progress = 0;

        while (iEnt < nEnt)
        {
            Long64_t currentEntry = pair_SlcEnt[iEnt].second;
            treeRaw_ToF->GetEntry(currentEntry);
            long long currentTsSlc = tsSlcRaw_ToF;

            // 临时容器
            vector<pair<double, size_t>> timeIndexPairs;
            vector<short> temp_brd, temp_ch, temp_fine;
            vector<double> temp_shift, temp_coarse, temp_tmStp;

            // 收集当前时间片所有有效信号
            while (iEnt < nEnt)
            {
                Long64_t ent = pair_SlcEnt[iEnt].second;
                treeRaw_ToF->GetEntry(ent);
                if (tsSlcRaw_ToF != currentTsSlc) break;

                for (int idx = 0; idx < nSigRaw_ToF; ++idx)
                {
                    if ((*coarseRaw_ToF)[idx] > 0 && (*fineRaw_ToF)[idx] > 0)
                    {
                        double timestamp = UseCoarse
                            ? TimeCrs_ToF * (*coarseRaw_ToF)[idx]
                            : TimeSft_ToF * (*shiftRaw_ToF)[idx];

                        size_t pos = timeIndexPairs.size();
                        timeIndexPairs.emplace_back(timestamp, pos);
                        temp_brd.push_back((*iBdRaw_ToF)[idx]);
                        temp_ch.push_back((*chRaw_ToF)[idx]);
                        temp_fine.push_back((*fineRaw_ToF)[idx]);
                        temp_shift.push_back(static_cast<double>((*shiftRaw_ToF)[idx]));
                        temp_coarse.push_back(static_cast<double>((*coarseRaw_ToF)[idx]));
                        temp_tmStp.push_back(timestamp);
                    }
                }
                ++iEnt;
            }

            if (temp_tmStp.empty()) continue;

            // 排序
            sort(timeIndexPairs.begin(), timeIndexPairs.end());

            // 填充输出 vector
            brdSort_ToF.clear();
            chSort_ToF.clear();
            fineSort_ToF.clear();
            shiftSort_ToF.clear();
            coarseSort_ToF.clear();
            tmStpSort_ToF.clear();

            for (const auto &p : timeIndexPairs)
            {
                size_t idx = p.second;
                brdSort_ToF.push_back(temp_brd[idx]);
                chSort_ToF.push_back(temp_ch[idx]);
                fineSort_ToF.push_back(temp_fine[idx]);
                shiftSort_ToF.push_back(temp_shift[idx]);
                coarseSort_ToF.push_back(temp_coarse[idx]);
                tmStpSort_ToF.push_back(p.first);
            }

            nSig_ToF = static_cast<int>(brdSort_ToF.size());
            tsSlcSort_ToF = currentTsSlc;
            treeSort_ToF->Fill();

            // 进度显示
            int newProgress = static_cast<int>((10 * iEnt) / nEnt);
            if (newProgress > progress)
            {
                progress = newProgress;
                printf("**********%d%% of %lld events of Run#%s have been processed**********\n",
                       10 * progress, nEnt, sRun_ToF.c_str());
            }
        }

        fSort->cd();
        treeSort_ToF->Write("", TObject::kOverwrite);
        fSort->Close();
        fRaw->Close();

        delete fSort;
        delete fRaw;

        clock_t finish = clock();
        cout << "\nTime for processing Run#" << sRun_ToF
             << " is: " << double(finish - start) / CLOCKS_PER_SEC << " s\n\n";
    }
}

#ifndef __CINT__
int main(int argc, char **argv)
{
    RawRoot2Sort_ToF();
    return 0;
}
#endif